package com.atmilan.quartz.utils.product;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.atmilan.quartz.config.RestTemplateConfig;
import com.atmilan.quartz.model.entity.europe.EuropeProduct;
import com.atmilan.quartz.model.entity.europe.EuropeProductSku;
import com.atmilan.quartz.model.entity.europe.EuropeProductSkuMerged;
import com.atmilan.quartz.utils.EuropeUtil;
import com.atmilan.quartz.utils.STAXUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.pagehelper.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 拉取商品源数据
 */

@Slf4j
@Service
public class EuropeProductUtil {

    @Autowired
    EuropeUtil europeUtil;

    @Value("${europe.url}")
    private String europeUrl;
    @Value("${europe.username}")
    private String europeUsername;
    @Value("${europe.password}")
    private String europePassword;
    private final String xmlGetGoodsById = "<tem:GetGoodsByGoodsID><tem:GoodsID>{}</tem:GoodsID></tem:GetGoodsByGoodsID>";
    private final String xmlGetGoodsDetailByGoodsID = "<tem:GetGoodsDetailByGoodsID><tem:GoodsID>{}</tem:GoodsID></tem:GetGoodsDetailByGoodsID>";
    private final String xmlGoodsPage = "<tem:GetGoodsListByPage><tem:PageNum>{}</tem:PageNum><tem:PageSize>{}</tem:PageSize></tem:GetGoodsListByPage>";

    /**
     * 获取远程Europe商品和详情
     * @Description:
     * @author daigb
     * @param @param barCode
     * @param @return
     * @return EuropeProduct
     * @throws
     */
    public EuropeProduct getEuropeByBarCode(String barCode) {
        if (StringUtil.isEmpty(barCode) || 4 >= barCode.length()) {
            return null;
        }
        String id = barCode.substring(4, barCode.length());

        try {
            log.info("--------------- 查询Europe商品远程数据, 商品id: {} ---------------", id);
            String auth = Base64.encode((europeUsername + ":" + europePassword).getBytes());
            String msg = EuropeUtil.getSendMsg(StrUtil.format(xmlGetGoodsById, id));
            String respXml = europeUtil.getEuropeXmlNew(auth, europeUrl, msg);
            log.info("--------------- 获取到Europe商品远程数据, 报文为: {} ---------------", respXml);
            if (StringUtil.isEmpty(respXml)) {
                log.info("--------------- 获取到Europe商品远程数据, respXml数据为空:{} ---------------", id);
                return null;
            }
            // 数据提取(获取单个商品数据)
            List<Map<String, Object>> europMapList = STAXUtil.getEuropMapList(respXml, "GetGoodsByGoodsID");
            if (CollectionUtils.isEmpty(europMapList)) {
                log.info("--------------- 获取到Europe商品远程数据, europMapList数据为空:{} ---------------", id);
                return null;
            }
            // 解析主商品
            Map<String, Object> europMap = europMapList.get(0);
            BigDecimal price = new BigDecimal((String) europMap.get("Price"));
            String goodsId = (String) europMap.get("ID");
            EuropeProduct europeGood = new EuropeProduct();
            // 解析商品sku
            List<EuropeProductSku> productSkus = getEuropeProductSkus(goodsId);
            europeGood = getEuropeProduct(europeGood, europMap, price, productSkus);
            // 解析商品skuMerged
            Map<String, Integer> sumStockMap = productSkus.stream().collect(Collectors.groupingBy(c -> c.getAttrKey(), Collectors.summingInt(EuropeProductSku::getQty)));
            productSkus = productSkus.stream().filter(sku -> StringUtil.isNotEmpty(sku.getAttrKey() + sku.getSize())).map(sku -> sku.setQty(sumStockMap.get(sku.getAttrKey()))).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(EuropeProductSku::getAttrKey))), ArrayList::new));
            europeGood.setSkuList(productSkus);
            List<EuropeProductSkuMerged> europeProductSkuMergeds = new ArrayList<EuropeProductSkuMerged>();
            productSkus.forEach(sku -> {
                if (0 < sku.getQty()) {
                    EuropeProductSkuMerged skuMerged = new EuropeProductSkuMerged();
                    skuMerged.setSkuId(sku.getId());
                    skuMerged.setGoodsId(sku.getGoodsId() + "");
                    skuMerged.setStock(sku.getQty());
                    skuMerged.setColor(sku.getColor());
                    skuMerged.setSize(sku.getSize());
                    skuMerged.setUpdateFlag(sku.getUpdateFlag());
                    skuMerged.setCreateTime(sku.getNewCreatedTime());
                    skuMerged.setEditTime(sku.getNewModifyTime());
                    skuMerged.setSuk(sku.getSuk());
                    skuMerged.setCreateTime(new Date());
                    europeProductSkuMergeds.add(skuMerged);
                }
            });

            europeGood.setSkuMergedList(europeProductSkuMergeds);
            return europeGood;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 获取远程Europe商品分页列表
     * @Description:
     * @author daigb
     * @param @param barCode
     * @param @return
     * @return EuropeProduct
     * @throws
     */
    public List<EuropeProduct> selectEuropePage(Integer pageNo, Integer pageSize) {
        List<EuropeProduct> europeProducts = new ArrayList<>();
        try {
            String auth = Base64.encode((europeUsername + ":" + europePassword).getBytes());
            String msg = EuropeUtil.getSendMsg(StrUtil.format(xmlGoodsPage, pageNo, pageSize));
            String respXml = europeUtil.getEuropeXmlNew(auth, europeUrl, msg);
            if (StringUtil.isEmpty(respXml)) {
                return europeProducts;
            }
            // 数据提取
            List<Map<String, Object>> europMapList = STAXUtil.getEuropMapList(respXml, "GetGoodsListByPage");
            if (CollectionUtils.isEmpty(europMapList)) {
                log.info("--------------- Europe商品抓取结束, pageNo: {}, pageSize: {}  ---------------", pageNo, europeProducts.size());
                return null;
            }
            // 解析主商品
            for (Map<String, Object> europMap : europMapList) {
                BigDecimal price = new BigDecimal((String) europMap.get("Price"));
                String goodsId = (String) europMap.get("ID");
                String stock = (String) europMap.get("Stock");
                // 价格或库存非法
                if (0 >= Integer.parseInt(stock) || -1 < BigDecimal.ZERO.compareTo(price)) {
                    continue;
                }
                EuropeProduct europeGood = new EuropeProduct();
                // 解析商品sku
                List<EuropeProductSku> productSkus = getEuropeProductSkus(goodsId);
                europeGood = getEuropeProduct(europeGood, europMap, price, productSkus);
                // 解析商品skuMerged
                Map<String, Integer> sumStockMap = productSkus.stream().collect(Collectors.groupingBy(c -> c.getAttrKey(), Collectors.summingInt(EuropeProductSku::getQty)));
                productSkus = productSkus.stream().filter(sku -> StringUtil.isNotEmpty(sku.getAttrKey() + sku.getSize())).map(sku -> sku.setQty(sumStockMap.get(sku.getAttrKey()))).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(EuropeProductSku::getAttrKey))), ArrayList::new));
                europeGood.setSkuList(productSkus);
                List<EuropeProductSkuMerged> europeProductSkuMergeds = new ArrayList<EuropeProductSkuMerged>();
                productSkus.forEach(sku -> {
                    if (0 < sku.getQty()) {
                        EuropeProductSkuMerged skuMerged = new EuropeProductSkuMerged();
                        skuMerged.setSkuId(sku.getId());
                        skuMerged.setGoodsId(sku.getGoodsId() + "");
                        skuMerged.setStock(sku.getQty());
                        skuMerged.setColor(sku.getColor());
                        skuMerged.setSize(sku.getSize());
                        skuMerged.setUpdateFlag(sku.getUpdateFlag());
                        skuMerged.setCreateTime(sku.getNewCreatedTime());
                        skuMerged.setEditTime(sku.getNewModifyTime());
                        skuMerged.setSuk(sku.getSuk());
                        skuMerged.setCreateTime(new Date());
                        europeProductSkuMergeds.add(skuMerged);
                    }
                });

                europeGood.setSkuMergedList(europeProductSkuMergeds);
                europeProducts.add(europeGood);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return europeProducts;
    }

    /**
     * 获得Europe商品详情
     * @Description:
     * @author daigb
     * @param @param goodsId
     * @param @return
     * @return List<EuropeProductSku>
     * @throws
     */
    public List<EuropeProductSku> getEuropeProductSkus(String goodsId) {
        try {
            String auth = Base64.encode((europeUsername + ":" + europePassword).getBytes());
            String sendMsg = EuropeUtil.getSendMsg(StrUtil.format(xmlGetGoodsDetailByGoodsID, goodsId));
            String respXml = europeUtil.getEuropeXmlNew(auth, europeUrl, sendMsg);
            List<Map<String, Object>> europMapList = STAXUtil.getEuropMapList(respXml, "GetGoodsDetailByGoodsID");

            Map<String, Object> map = europMapList.get(0);
            List<EuropeProductSku> list = new ArrayList<>();
            @SuppressWarnings("unchecked")
            List<HashMap<String, Object>> stockList = (List<HashMap<String, Object>>) map.get("Stock");

            stockList.forEach(item -> {
                EuropeProductSku europeProductSku = new EuropeProductSku();
                int qty = Integer.parseInt((String) item.get("Qty"));
                getEuropeProductSku(qty, europeProductSku, map, item, stockList);
                list.add(europeProductSku);
            });
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    // Europe商品构建
    private EuropeProduct getEuropeProduct(EuropeProduct europeGood, Map<String, Object> map, BigDecimal price, List<EuropeProductSku> productSkus) {
        try {
            europeGood.setGoodId(Integer.parseInt((String) map.get("ID")));
            europeGood.setModel((String) map.get("Model"));
            europeGood.setVariante((String) map.get("Variante"));
            europeGood.setSeason((String) map.get("Season"));
            europeGood.setCollection((String) map.get("Collection"));
            europeGood.setSupplierId(Integer.parseInt((String) map.get("SupplierID")));
            europeGood.setBrandId(Integer.parseInt((String) map.get("BrandID")));
            europeGood.setParentCategoryId(Integer.parseInt((String) map.get("ParentCategoryID")));
            europeGood.setCategoryId(Integer.parseInt((String) map.get("CategoryID")));
            europeGood.setTypeId(Integer.parseInt((String) map.get("TypeID")));
            europeGood.setCode((String) map.get("Code"));
            europeGood.setGoodsName((String) map.get("GoodsName"));
            europeGood.setReferencePrice(new BigDecimal((String) map.get("ReferencePrice")));
            europeGood.setPrice(price);
            europeGood.setDiscount((String) map.get("Discount"));
            europeGood.setStock(Integer.parseInt((String) map.get("Stock")));
            europeGood.setMainPicNo((String) map.get("MainPicNo"));
            europeGood.setNewModifyTime(DateUtil.date());
            europeGood.setNewCreatedTime(DateUtil.date());
            //获取商品sku的缩略图和商品相册
            if (productSkus != null && productSkus.size() > 0) {
                if (StringUtil.isNotEmpty(productSkus.get(0).getPictures())) {
                    @SuppressWarnings("rawtypes")
                    List<Map> lists = JSONObject.parseArray(productSkus.get(0).getPictures(), Map.class);
                    List<Map<String, Object>> list = new ArrayList<>();
                    lists.forEach(vo -> {
                        Map<String, Object> map1 = new HashMap<>();
                        map1.put("img_original", (String) vo.get("PictureUrl"));
                        map1.put("thumb_url", vo.get("PictureThumbUrl"));
                        list.add(map1);
                    });
                    europeGood.setGallery(JSONObject.toJSONString(list));
                    if (!CollectionUtils.isEmpty(lists)) {
                        europeGood.setGoodsImg((String) lists.get(0).get("PictureUrl"));
                    }
                } else {
                    europeGood.setGallery("");
                    europeGood.setGoodsImg("");
                }
            } else {
                europeGood.setGallery("");
                europeGood.setGoodsImg("");
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        try {
            String oldCreatedTime = (String) map.get("CreatedTime");
            if (oldCreatedTime != null && StringUtil.isNotEmpty(oldCreatedTime)) {
                if (oldCreatedTime.endsWith("AM")) {
                    oldCreatedTime = oldCreatedTime.replace(" AM", "");
                    europeGood.setOldCreatedTime(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(oldCreatedTime));//map.get("CreatedTime")
                } else {
                    oldCreatedTime = oldCreatedTime.replace(" PM", "");
                    europeGood.setOldCreatedTime(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(oldCreatedTime));//map.get("CreatedTime")
                }
            } else {
                europeGood.setOldCreatedTime(null);
            }
            String oldModifyTime = (String) map.get("ModifyTime");
            if (oldModifyTime != null && StringUtil.isNotEmpty(oldModifyTime)) {
                if (oldModifyTime.endsWith("AM")) {
                    oldModifyTime = oldModifyTime.replace(" AM", "");
                    europeGood.setOldModifyTime(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(oldModifyTime));
                } else {
                    oldModifyTime = oldModifyTime.replace(" PM", "");
                    europeGood.setOldModifyTime(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(oldModifyTime));
                }
            } else {
                europeGood.setOldModifyTime(null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return europeGood;
    }

    // Europe商品sku获取
    private EuropeProductSku getEuropeProductSku(int qty, EuropeProductSku europeProductSku, Map<String, Object> map, HashMap<String, Object> item, List<HashMap<String, Object>> stockList) {
        try {
            europeProductSku.setId((String) map.get("ID") + "-" + item.get("Size"));
            europeProductSku.setGoodsId(Integer.parseInt((String) map.get("ID")));
            europeProductSku.setSuperColor((String) map.get("SuperColor"));
            europeProductSku.setColor((String) map.get("Color"));
            europeProductSku.setFabric((String) map.get("Fabric"));
            europeProductSku.setComposition((String) map.get("Composition"));
            europeProductSku.setSizeAndFit((String) map.get("SizeAndFit"));
            europeProductSku.setMadeIn((String) map.get("MadeIn"));

            if (StringUtil.isNotEmpty(map.get("Pictures").toString())) {
                @SuppressWarnings("unchecked")
                List<HashMap<String, Object>> pictures = (List<HashMap<String, Object>>) map.get("Pictures");
                europeProductSku.setPictures(JSONObject.toJSONString(pictures));
            }
            if (StringUtil.isNotEmpty(map.get("Stock").toString())) {
                @SuppressWarnings("unchecked")
                List<HashMap<String, Object>> stock = (List<HashMap<String, Object>>) map.get("Stock");
                europeProductSku.setStock(JSONObject.toJSONString(stock));
            }
            europeProductSku.setSize((String) item.get("Size"));
            europeProductSku.setQty(qty);
            europeProductSku.setSuk((String) map.get("Color") + "," + (String) item.get("Size"));
            String oldCreatedTime = (String) map.get("CreatedTime");
            if (oldCreatedTime != null && StringUtil.isNotEmpty(oldCreatedTime)) {
                if (oldCreatedTime.endsWith("AM")) {
                    oldCreatedTime = oldCreatedTime.replace(" AM", "");
                    europeProductSku.setOldCreatedTime(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(oldCreatedTime));
                } else {
                    oldCreatedTime = oldCreatedTime.replace(" PM", "");
                    europeProductSku.setOldCreatedTime(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(oldCreatedTime));
                }
            } else {
                europeProductSku.setOldCreatedTime(null);
            }
            String oldModifyTime = (String) map.get("ModifyTime");
            if (oldModifyTime != null && StringUtil.isNotEmpty(oldModifyTime)) {
                if (oldModifyTime.endsWith("AM")) {
                    oldModifyTime = oldModifyTime.replace(" AM", "");
                    europeProductSku.setOldModifyTime(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(oldModifyTime));
                } else {
                    oldModifyTime = oldModifyTime.replace(" PM", "");
                    europeProductSku.setOldModifyTime(new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse(oldModifyTime));
                }
            } else {
                europeProductSku.setOldModifyTime(null);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return europeProductSku;
    }

}
